package com.common.distributed.sharding.algorithm;

import org.springframework.beans.BeanUtils;

import com.common.distributed.sharding.common.exception.DistributedParseException;
import com.mysql.jdbc.StringUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * 对Object的属性的读取写入工具
 * @author liubing
 *
 */
public class BeanPropertyAccessUtil {

    /**
     * 通过反射设置一个对象的某个属性值
     *
     * @param propertyName,name of the property
     * @param propertyValue,new value of the property
     * @param object,the        object which contains the property
     */
    public static void setPropertyValue(final String propertyName, final Object propertyValue, final Object object) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isNullOrEmpty(propertyName) || object == null) {
            throw new IllegalArgumentException("'propertyName' cann't be null or empty,'object' cann't be null!");
        }
        PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(object.getClass(), propertyName);
        if (descriptor != null && descriptor.getWriteMethod() != null) {
            descriptor.getWriteMethod().invoke(object, propertyValue);
        }
    }

    /**
     * 通过反射获取一个对象的某个属性值
     *
     * @param propertyName,name of the property
     * @param object,the        object which contains the property
     * @return the value object of the property
     */
    public static Object getPropertyValue(final String propertyName, final Object object) throws InvocationTargetException, IllegalAccessException {
        if (StringUtil.isNullOrEmpty(propertyName) || object == null) {
            throw new IllegalArgumentException("'propertyName' cann't be null or empty,'object' cann't be null!");
        }
        PropertyDescriptor descriptor = BeanUtils.getPropertyDescriptor(object.getClass(), propertyName);
        if (descriptor != null && descriptor.getReadMethod() != null) {
            return descriptor.getReadMethod().invoke(object);
        }
        return null;
    }
    
    /**
	 * 重写实体参数类表名
	 * @param parameterObj
	 * @param tableNameField
	 * @param physicalTableName
	 * @throws RouteException
	 */
	public static void rewriteTableName(final Object parameterObj,final String tableNameField, final String physicalTableName) throws DistributedParseException {
        try {
            if (parameterObj instanceof Map) {
                ((Map) parameterObj).put(tableNameField, physicalTableName);
            } else if (parameterObj != null) {
                setPropertyValue(tableNameField, physicalTableName, parameterObj);
            }
        } catch (Exception e) {
            throw new DistributedParseException("rewrite table name error!", e);
        }
    }

}
